
include 'win64ax.inc'
include 'blocks64.inc'
include 'macro\fastenter64a.inc'


macro .EH_PROC_START a, b
{
  a#b:
  macro .END_PROLOG
  \{
    b#.unwind.end_prolog:
  \}
  macro .LABEL c
  \{
    b#.\#c:
  \}
  macro .BASE@EH_PROC_END
  \{
    b#._endfn:
  \}
}

macro .EH_PROC_END
{
  .BASE@EH_PROC_END
  purge .END_PROLOG
  purge .BASE@EH_PROC_END
}

macro .SAVE_REGS reglist {
  irps reg, reglist \{ push reg \}
  macro .BASE@RESTORE_REGS
  \{ irps reg, reglist \\{ reverse pop reg \\} \}
}

macro .RESTORE_REGS {
  .BASE@RESTORE_REGS
  purge .BASE@RESTORE_REGS
}

entry start

section '.text' code readable executable

; GetCurrentProcess returns -1
; GetCurrentThread  returns -2

HANDLE_CURRENT_PROCESS equ (-1)
HANDLE_CURRENT_THREAD  equ (-2)

	db	16 dup(0xCC)
.EH_PROC_START start
	db	0x40
	.SAVE_REGS rbx rbp rsi rdi r12 r13 r14 r15
	mov	rbp, rsp
	local_fp equ rbp
  .END_PROLOG
	or	dword [rsp-0x1000], 0
	sub	rsp, 37*8
	mov	[local_fp-8], rsp
	call	[GetCommandLine]
	mov	[local_fp-2*8], rax
	xor	r15d, r15d
	xor	ecx, ecx
	xor	edx, edx
	xor	r8d, r8d
	call	[CreateMutex]
	test	rax, rax
	mov	[local_fp-3*8], rax
	jz	._no_mutex
	lea	rcx, [local_fp-7*8]
	mov	rdx, [local_fp-2*8]
	call	_splitcmdline2module
	jz	._release_lib_set
	mov	rax, 'MYCON_'
	lea	rbx, [local_fp-15*8]
	lea	rdi, [local_fp-18*8]
	mov	rcx, rdi
	mov	[local_fp-15*8], rax
	call	_make_identifier._base
	.repeat
		lea	rcx, [rbx+6]
		mov	rdx, rdi
		call	_make_identifier
		lea	rcx, [local_fp-9*8]
		mov	rdx, 0x6000
		inc	qword [rdi+8]
		mov	r8, rbx
		call	_fMap
	.until	~CARRY?
	jz	._release_lib_set
	; pusha in x64 is invalid
	lea	rbx, [local_fp-27*8]
	mov	rsi, rax
	xor	r14d, r14d
	mov	rcx, rbx
	mov	rdx, 72
	lea	r8, [_myconhost_exe__s]
	lea	r9, [local_fp-15*8+6]
	call	[snprintf]
	mov	rcx, rbx
	lea	rdx, [local_fp-18*8]
	lea	rdi, [rdx-8]
	mov	[rdi], r14
	mov	rbx, rdx
	stc
	call	_newproc
	mov	rcx, [rdi]
	sub	rcx, r14
	call	._test_bufferoflw
	test	eax, eax
	jz	._newproc_failure
	lea	r14, [rsi+80*25*12]
	mov	rax, [local_fp-3*8]
	call	._dup_handle_1a
	test	rax, rax
	jz	._resume_proc_failure
	mov	r10, rax
	call	._dup_handle_1b
	mov	[r14], rax
	mov	[r14+8], r10
	lea	rcx, [r14+16]
	mov	rdx, [rbx+8]
	mov	qword [rcx], 0
	call	_waitforalerted.1
	test	eax, eax
	js	._resume_proc_failure
	cmp	eax, 0x101
	mov	rcx, rbx
	mov	edx, 2
	call	_closehandles
	jnz	._resume_proc_failure2
	lea	rcx, [local_fp-7*8]
	mov	rdx, rsi
	mov	r8, [local_fp-3*8]
	xor	r9d, r9d		; r9 is not used
	mov	r10, [gs:dword 0x30]
	mov	r11, [r10+0x28] 	; Save ArbitraryUserPointer
	call	._run_routine
	mov	[r10+0x28], r11 	; Restore ArbitraryUserPointer
  .restore_status:
	lea	rcx, [local_fp-9*8]
	call	_fUnmap
  .release_lib:
	mov	rcx, [local_fp-7*8]
	.if	rcx
		call	[FreeLibrary]
		mov	rcx, [local_fp-4*8]
		call	[free]
	.endif
	mov	rcx, [local_fp-3*8]
	call	[CloseHandle]
	mov	ecx, r15d
  ._no_mutex2:
	restore local_fp
	lea	rsp, [rbp+0]
	.RESTORE_REGS
	jmp	._exitproc
.EH_PROC_END
	align	16

.EH_PROC_START ,._exitproc
	sub	rsp, 5*8
  .END_PROLOG
	call	[ExitProcess]
	int3
	add	rsp, 5*8
	ret
.EH_PROC_END
	align	16

.EH_PROC_START ,._release_lib_set
	inc	r15d
	jmp	.release_lib
.EH_PROC_END
	align	8

.EH_PROC_START ,._resume_proc_failure
	mov	rcx, [rbx]
	mov	rdx, -1
	call	[TerminateProcess]
	mov	rcx, rbx
	mov	edx, 2
	call	_closehandles
  ._newproc_failure:
  ._resume_proc_failure2:
	inc	r15d
	jmp	.restore_status
.EH_PROC_END
	align	16

.EH_PROC_START ,._no_mutex
	mov	ecx, 1
	jmp	._no_mutex2
.EH_PROC_END
	align	16

.EH_PROC_START ,._dup_handle_1a
	push	r10
	sub	rsp, 8*8
  .END_PROLOG
  @@:
	mov	[rsp+7*8], rax
	call	[GetCurrentProcess]
	mov	rcx, rax			; hSourceProcessHandle
	mov	r8, [rbx]			; hTargetProcessHandle
	lea	r9, [rsp+7*8]			; lpTargetHandle
	mov	rdx, [r9]			; hSourceHandle
	xor	eax, eax
	mov	[rsp+4*8], eax			; dwDesiredAccess
	mov	[rsp+5*8], eax			; bInheritHandle
	mov	eax, DUPLICATE_SAME_ACCESS
	mov	[rsp+6*8], eax			; dwOptions
	call	[DuplicateHandle]
	mov	eax, eax
	test	eax, eax
	cmovnz	rax, [rsp+7*8]
	add	rsp, 8*8
	pop	r10
	ret
.EH_PROC_END
	align	16

.EH_PROC_START ,._dup_handle_1b
	push	r10
	sub	rsp, 8*8
  .END_PROLOG
	call	[GetCurrentThread]
	jmp	@b
.EH_PROC_END
	align	16

.EH_PROC_START ,._run_routine
	db	0x40
	; Save non-volatiles
	.SAVE_REGS rbx rbp rsi rdi r10 r11 r12 r13 r14 r15
	sub	rsp, 5*8
  .END_PROLOG
	mov	rsi, [rcx+8]
	mov	rdi, [rcx+2*8]
	lea	r10, [$ - rva $]
	mov	rcx, rdx
	mov	rdx, rdi
	call	rsi
	add	rsp, 5*8
	; Restore non-volatiles
	.RESTORE_REGS
.EH_PROC_END
	ret
	align	16

start._test_bufferoflw:
	.if	~rcx
		db	0xF3
		ret
	.endif
.EH_PROC_START ,.1
	xor	r10d, r10d
	mov	rbx, [rsp+16]
  .LABEL save_rbx
	or	dword [rsp-0x1000], 0
	sub	rsp, 0x168
  .END_PROLOG
	lea	rbx, [rsp+0x40]
	mov	rcx, \
		FORMAT_MESSAGE_IGNORE_INSERTS or	\
		FORMAT_MESSAGE_FROM_SYSTEM or		\
		FORMAT_MESSAGE_MAX_WIDTH_MASK
	xor	edx, edx
	mov	r8d, 0x502
	mov	r9d, (1 shl 10)
	mov	[rsp+4*8], rbx
	mov	dword [rsp+5*8], 0x120
	mov	[rsp+6*8], rdx
	call	[FormatMessage]
	.if	eax
		xor	ecx, ecx	; HWND_DESKTOP
		mov	rdx, rbx
		xor	r8d, r8d
		mov	r9d, MB_ICONERROR
		call	[MessageBox]
	.endif
	mov	rbx, [rsp+0x178]
	add	rsp, 0x168
	jmp	[abort]
.EH_PROC_END
	align	16

.EH_PROC_START _make_identifier
	.SAVE_REGS rbx rsi rdi
	sub	rsp, 4*8
  .END_PROLOG
	lea	rbx, [base36_c]
	mov	rsi, [rdx+8]
	mov	rdi, rcx
	mov	rcx, [rdx]
	call	.1
	mov	rcx, rsi
	call	.1a
	mov	byte [rdi], 0
	mov	rax, rdi
	add	rsp, 4*8
	.RESTORE_REGS
	ret
.EH_PROC_END
	align	16

.EH_PROC_START ,.1
	; uses RBX and RDI
	push	rcx
  .END_PROLOG
	test	rcx, rcx
	jnz	.1b	; JRCXNZ?
	pop	rcx
	ret
.EH_PROC_END
	align	16

.EH_PROC_START ,.1a
	; uses RBX and RDI
	push	rcx
  .END_PROLOG
	mov	eax, ecx
	and	eax, 3
	mov	al, [rbx+rax+0x20]
	stosb
	shr	rcx, 2
	.if	rcx
  .1b:
		.repeat
			mov	al, cl
			and	al, 0x1F
			xlatb
			stosb
			shr	rcx, 5
		.until	ZERO?
	.endif
	pop	rcx
	ret
.EH_PROC_END
	align	16

.EH_PROC_START ,._base
	push	rbx
	sub	rsp, 4*8
  .END_PROLOG
	mov	rbx, rcx
	call	[GetCurrentProcessId]
	lea	rcx, [rbx+8]
	mov	[rbx], eax
	; QueryPerformanceCounter always succeed and return non-zero
	call	[QueryPerformanceCounter]
	add	rsp, 4*8
	pop	rbx
	ret
.EH_PROC_END
	align	16

.EH_PROC_START _fMap
	db	0x40
	.SAVE_REGS rbx rbp rsi rdi r12
	sub	rsp, 6*8
  .LABEL unwind.alloc
	mov	rbp, rsp
  .END_PROLOG
	mov	rsi, rcx
	mov	edi, edx
	mov	[rsp+4*8], edi
	mov	[rsp+5*8], r8
	mov	rcx, INVALID_HANDLE_VALUE
	xor	edx, edx
	mov	r8d, PAGE_READWRITE
	xor	r9d, r9d
	call	[CreateFileMapping]
	mov	r12, rax
	call	[GetLastError]
	test	r12, r12
	jz	.1
	cmp	eax, 0xB7
	mov	bl, 1
	je	.2
	xor	ebx, ebx
	mov	rcx, r12
	mov	edx, FILE_MAP_READ or FILE_MAP_WRITE
	xor	r8d, r8d
	xor	r9d, r9d
	mov	[rsp+4*8], rdi
	call	[MapViewOfFile]
	test	rax, rax
	jz	.2
	mov	[rsi], r12
	mov	[rsi+8], rax
  .epilog:
	lea	rsp, [rbp+6*8]
	.RESTORE_REGS
	ret
.EH_PROC_END
	align	16

.EH_PROC_START ,.1
	cmp	eax, 6	; 6 means ERROR_INVALID_HANDLE
	sete	cl
	xor	eax, eax
	shr	cl, 1
	jmp	.epilog
.EH_PROC_END
	align	16

.EH_PROC_START ,.2
	mov	rcx, r12
	call	[CloseHandle]
	xor	eax, eax
	shr	bl, 1
	jmp	.epilog
.EH_PROC_END
	align	16

.EH_PROC_START _fUnmap
	push	rbx
	sub	rsp, 4*8
  .END_PROLOG
	mov	rbx, [rcx]
	.if	rbx
		mov	rcx, [rcx+8]
		call	[UnmapViewOfFile]
		mov	rcx, rbx
		call	[CloseHandle]
	.endif
	add	rsp, 4*8
	pop	rbx
	ret
.EH_PROC_END
	align	16

.EH_PROC_START _xcpt_table_delete
	sub	rsp, 5*8
  .END_PROLOG
	call	[RtlDeleteFunctionTable]
	.if	eax
		add	rsp, 5*8
		ret
	.endif
	add	rsp, 5*8
	jmp	[abort]
.EH_PROC_END
	align	16

.EH_PROC_START _splitcmdline2module
	db	0x40
	.SAVE_REGS rbx rbp rsi rdi r12 r13 r14 r15
	mov	rbp, rsp
  .END_PROLOG
	sub	rsp, 8*13
	and	rsp, -16
	mov	[rbp-8], rcx
	mov	rdi, rdx
	mov	eax, 0x20
	or	rcx, -1
	repe	scasb
	mov	ecx, HEAP_NO_SERIALIZE
	mov	edx, 0x1000
	xor	r8d, r8d
	call	[HeapCreate]
	test	rax, rax
	jz	.epilog1d
	mov	[rbp-5*8], rax
	dec	rdi
	mov	rcx, rax
	lea	rdx, [rsp+4*8]
	mov	[rdx], rdi
	call	.1a
	test	rax, rax
	jz	.epilog1c
	mov	[rbp-2*8], rax
	lea	rcx, [rsp+5*8]
	lea	rdx, [rbp-4*8]
	call	.getlibproc1a
	test	rax, rax
	jz	.epilog1b
	mov	rcx, [rbp-5*8]
	call	[HeapDestroy]
	mov	rax, [rbp-4*8]
	mov	rdx, [rbp-3*8]
	mov	rcx, [rbp-2*8]
	jmp	.epilog1e
	align	16
  .epilog1b:
	mov	rcx, [rbp-2*8]
	call	[free]
  .epilog1c:
	mov	rcx, [rbp-5*8]
	call	[HeapDestroy]
  .epilog1d:
	xor	eax, eax
	xor	ecx, ecx
	xor	edx, edx
  .epilog1e:
	restore local_fp
	mov	rbx, [rbp-8]
	mov	[rbx], rax
	mov	[rbx+8], rdx
	mov	[rbx+2*8], rcx
	test	rax, rax
	lea	rsp, [rbp+0]
	.RESTORE_REGS
	ret
.EH_PROC_END
	align	16

.EH_PROC_START ,.1a
	mov	r12, rcx
	mov	r13, rdx
	push	rbp
  .LABEL unwind.push_rbp
	mov	rbp, rsp
  .END_PROLOG
	mov	r10, rbp
	xor	edx, edx
	call	.get_next
	mov	ecx, 8
	mov	edx, 3
	call	.get_next
	mov	ecx, 2*8
	mov	edx, 2
	call	.get_next
	mov	rcx, [r13]
	lea	rsp, [rbp]
	pop	rbp
	jmp	[strdup]
	align	16
.heapop_return:
	xor	eax, eax
	lea	rsp, [rbp]
	pop	rbp
	ret
.EH_PROC_END
	align	16

.EH_PROC_START ,.heapalloc1
	; r10 = static chain pointer
	push	rbp
	sub	rsp, 4*8
  .END_PROLOG
	mov	rbp, r10
	xor	edx, edx
	call	[HeapAlloc]
	test	rax, rax
	jz	.heapop_return
  .heapop_epilog:
	add	rsp, 4*8
	pop	rbp
  @@:	rep	ret
.EH_PROC_END
	align	16

.heapfindsep1:
	.BLOCK_BEGIN
	jz	BLOCK_END
.EH_PROC_START ,.heapfindsep1a
	push	rbp
	sub	rsp, 4*8
  .END_PROLOG
	mov	rbp, r10
	mov	[rsp+6*8], rcx
	lea	rdx, [_my_separators]
	call	[strpbrk]
	jmp	@f
.EH_PROC_END
	.BLOCK_END
	align	16

	mov	edx, ' '
.EH_PROC_START ,.heapstrchr1
	push	rbp
	sub	rsp, 4*8
  .END_PROLOG
	mov	rbp, r10
	mov	[rsp+6*8], rcx
	call	[strchr]
  @@:
	.if	~rax
		mov	rcx, [rsp+6*8]
		call	[strlen]
		test	rax, rax
		jz	.heapop_return
		jmp	.heapop_epilog
	.endif
	sub	rax, [rsp+6*8]
	jz	.heapop_return
	jmp	.heapop_epilog
.EH_PROC_END
	align	16

.EH_PROC_START ,.getlibproc1a
	db	0x40
	.SAVE_REGS rbx rbp rsi rdi r13
	mov	rbp, rsp
  .END_PROLOG
	frame
	mov	rsi, rcx
	mov	rbx, rdx
	invoke	LoadLibrary, qword [rsi]
	.if	eax
		mov	rdi, rax
		invoke	GetProcAddress, rdi, qword [rsi+8]
		.if	~eax
			invoke	FreeLibrary, rdi
			xor	eax, eax
			jmp	.getlibproc1a.epilog1
		.endif
		mov	[rbx], rdi
		mov	[rbx+8], rax
	.endif
  .getlibproc1a.epilog1:
	endf
	.RESTORE_REGS
	ret
.EH_PROC_END
	align	16

.EH_PROC_START ,.get_next
	; r10 = static chain pointer
	; rcx = offset
	; rdx = flags
	; expected DF is cleared
	push	rbp r10 r12
  .LABEL unwind.push_rcx
	sub	rsp, 6*8
  .END_PROLOG
	add	rcx, r13
	mov	[rsp+4*8], rcx
	mov	[rsp+5*8], rdx
	mov	ebx, edx
	and	rbx, 1
	mov	rsi, [r13]
	mov	rcx, rsi
	.if	byte [esi] = '"'
		inc	rcx
		inc	rsi
		mov	edx, '"'
		call	.heapstrchr1
		xor	ecx, ecx
		lea	rdi, [rsi+rax]
		cmp	byte [rdi], '"'
		sete	cl
		add	rdi, rcx
	.else
		test	ebx, ebx
		call	.heapfindsep1
		lea	rdi, [rsi+rax]
	.endif
	mov	r8, rax
  .LABEL 1a
	mov	eax, ' '
	or	ecx, -1
	repe	scasb
	movzx	eax, byte [rdi-1]
	dec	ebx
	js	.get_next.1b
	sub	eax, ','
	jz	.get_next.1a
	dec	eax
	jz	.get_next.1c
  .LABEL 1b
	dec	rdi
	mov	[r13], rdi
	test	byte [rsp+5*8], 2
	.if	~ZERO?
		mov	rcx, r12
		mov	rdi, r8
		inc	r8
		mov	r10, [rsp+7*8]
		call	.heapalloc1
		and	byte [rax+rdi], 0
		mov	rcx, rax
		mov	rdx, rsi
		mov	r8, rdi
		call	[memcpy]
		mov	rcx, [rsp+4*8]
		mov	[rcx], rax
	.endif
	add	rsp, 6*8
	pop	r12 r10 rbp
	ret
	align	16

  .LABEL 1c
	ud2
.EH_PROC_END
	align	16

.EH_PROC_START _newproc
	db	0x40
	.SAVE_REGS rbx rbp rsi rdi r12
	mov	rbx, rcx
	setc	sil
	lea	rdi, [rsp - 136]
	mov	r12, rdi
	sub	rsp, 136 + 11 * 8
  .LABEL unwind.alloc
	mov	rbp, rsp
  .END_PROLOG
	movzx	esi, sil
	mov	ecx, 136 / 8
	xor	eax, eax
	rep	stosq
	mov	rax, rsp
	imul	esi, esi, CREATE_SUSPENDED
	mov	rdi, rdx
	xor	ecx, ecx	; lpApplicationName = NULL
	mov	rdx, rbx	; lpCommandLine
	xor	r8d, r8d	; lpProcessAttributes = NULL
	xor	r9d, r9d	; lpThreadAttributes = NULL
	mov	[rsp+4*8], rcx	; bInheritHandles = FALSE
	mov	[rsp+5*8], rsi	; dwCreationFlags
	mov	[rsp+6*8], rcx	; lpEnvironment = NULL
	mov	[rsp+7*8], rcx	; lpCurrentDirectory = NULL
	mov	[rsp+8*8], r12	; lpStartupInfo
	mov	[rsp+9*8], rdi	; lpProcessInformation
	call	[CreateProcess]
	.if	~eax
		mov	eax, eax
		mov	ecx, 3
		rep	stosq
	.endif
	lea	rsp, [rbp + 136 + 11 * 8]
	.RESTORE_REGS
	ret
.EH_PROC_END
	align	16

.EH_PROC_START _closehandles
	db	0x40
	.SAVE_REGS rbx rbp rsi
	mov	rbp, rsp
  .END_PROLOG
	pushf
	sub	rsp, 5*8
	cld
	mov	rsi, rcx
	mov	ebx, edx
	.repeat
		lodsq
		.if	rax
			mov	rcx, rax
			call	[CloseHandle]
		.endif
	._until ebx
	lea	rsp, [rbp-8]
	popf
	.RESTORE_REGS
	ret
.EH_PROC_END
	align	16

.EH_PROC_START _waitforalerted
	sub	rsp, 5*8
  .END_PROLOG
	.repeat
		mov	rcx, rsi
		mov	edx, TRUE
		xor	r8d, r8d
		call	[NtWaitForSingleObject]
	.until	eax <> 0x102
	add	rsp, 5*8
	ret
.EH_PROC_END
	align	8

.EH_PROC_START ,.1
	.SAVE_REGS rbx rsi r10 r11
	sub	rsp, 5*8
  .END_PROLOG
	mov	rbx, rcx
	mov	rsi, rdx
	mov	rcx, rdx
	lea	rdx, [rsp+4*8]
	call	[NtResumeThread]
	test	eax, eax
	js	.1z
  .1b:
	call	_waitforalerted
	test	eax, eax
	js	.1z
	lea	ecx, [rax-0x101]
	mov	edx, [rbx]
	neg	ecx
	dec	edx
	ja	.1b
  .1z:
	add	rsp, 5*8
	.RESTORE_REGS
	ret
.EH_PROC_END
	align	16

.EH_PROC_START ,.resume_fail
	call	[abort]
	jmp	.1z
.EH_PROC_END
	align	16

section '.data' data readable writeable
	_myconhost_exe__s \
		 db """myconhost.exe"" %s", 0
	align	 8
	start._save_rbp \
		 rq 1
	start._mutex_evt \
		 rq 1
	align	 16
	base36_c db "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	_my_separators db ' ,', 0

section '.pdata' readable writeable

macro _runtime_fn_nolabel a
{
  dd RVA a, RVA a#._endfn, RVA a#.unwind
}

macro _runtime_fn a
{
  a#.@funci dd RVA a, RVA a#._endfn, RVA a#.unwind
}

macro _runtime_fn_lnk a, b
{
  a#.@funci dd RVA a, RVA a#._endfn, RVA b#.@funci+1
}

macro _runtime_unw a
{
  a#.unwind:
  _orig equ a
  _sz_prolog equ (.end_prolog - a)
  macro sv b,c,d
  \{
    dw (a\#b-a)+0x400+(c shl 12),d
  \}
}

macro _runtime_unw_end
{
  purge sv
  restore _orig
  restore _sz_prolog
}

; UWOP_PUSH_NONVOL = 0
; UWOP_ALLOC_LARGE = 1
; UWOP_ALLOC_SMALL = 2
; UWOP_SET_FPREG   = 3
; UWOP_SAVE_NONVOL = 4

  data 3   ; IMAGE_DIRECTORY_ENTRY_EXCEPTION
	_runtime_fn	start
	_runtime_fn	start._exitproc
	_runtime_fn_lnk start._release_lib_set, start
	_runtime_fn_lnk start._resume_proc_failure, start
	_runtime_fn_lnk start._no_mutex, start
	_runtime_fn	start._dup_handle_1a
	_runtime_fn	start._dup_handle_1b
	_runtime_fn	start._run_routine
	_runtime_fn	start._test_bufferoflw.1
	_runtime_fn	_make_identifier
	_runtime_fn	_make_identifier.1
	_runtime_fn	_make_identifier.1a
	_runtime_fn	_make_identifier._base
	_runtime_fn	_fMap
	_runtime_fn_lnk _fMap.1, _fMap
	_runtime_fn_lnk _fMap.2, _fMap
	_runtime_fn	_fUnmap
	_runtime_fn	_xcpt_table_delete
	_runtime_fn	_splitcmdline2module
	_runtime_fn	_splitcmdline2module.1a
	_runtime_fn	_splitcmdline2module.heapalloc1
	_runtime_fn	_splitcmdline2module.heapfindsep1a
	_runtime_fn	_splitcmdline2module.heapstrchr1
	_runtime_fn	_splitcmdline2module.getlibproc1a
	_runtime_fn	_splitcmdline2module.get_next
	_runtime_fn	_newproc
	_runtime_fn	_closehandles
	_runtime_fn	_waitforalerted
	_runtime_fn	_waitforalerted.1
	_runtime_fn_lnk _waitforalerted.resume_fail, _waitforalerted.1
  end data

  align 16

  _runtime_unw start
	; FrameRegister = RBP
	db 1 + (0 shl 3)	; Version 3 & Flags 5
	db _sz_prolog		; SizeOfProlog
	db 9			; CountOfCodes
	db 5			; FrameRegister 4 & FrameOffset 4
	dw _sz_prolog + 0x0300
	dw 0xF00D, 0xE00B, 0xD009, 0xC007, 0x7005, 0x6004, 0x5003, 0x3002, 0
	dd 0
	dd 0
  _runtime_unw_end

  _runtime_unw start._exitproc
	db 1 + (0 shl 3)
	db _sz_prolog
	db 1
	db 0
	dw _sz_prolog + 0x4200, 0
	dd 0
	dd 0
  _runtime_unw_end

  _runtime_unw start._dup_handle_1a
	db 1 + (0 shl 3)
	db _sz_prolog
	db 2
	db 0
	dw _sz_prolog + 0x7200, 0xA002
	dd 0
	dd 0
  _runtime_unw_end

  _runtime_unw start._dup_handle_1b
	db 1 + (0 shl 3)
	db _sz_prolog
	db 2
	db 0
	dw _sz_prolog + 0x7200, 0xA002
	dd 0
	dd 0
  _runtime_unw_end

  _runtime_unw start._run_routine
	db 1 + (0 shl 3)
	db _sz_prolog
	db 11
	db 0
	dw _sz_prolog + 0x4200
	dw 0xF011, 0xE00F, 0xD00D, 0xC00B, 0xB009, 0xA007, 0x7005, 0x6004, 0x5003, 0x3002, 0
	dd 0
	dd 0
  _runtime_unw_end

  _runtime_unw start._test_bufferoflw.1
	db 1 + (0 shl 3)
	db _sz_prolog
	db 4
	db 0
	sv .save_rbx, 3, (0x178 / 8)
	dw _sz_prolog + 0x0100, (0x168 / 8)
	dd 0
  _runtime_unw_end

  _runtime_unw _make_identifier
	db 1 + (0 shl 3)
	db _sz_prolog
	db 4
	db 0
	dw _sz_prolog + 0x3200
	dw 0x7003, 0x6002, 0x3001
	dd 0
  _runtime_unw_end

  _runtime_unw _make_identifier.1
	db 1 + (0 shl 3)
	db _sz_prolog
	db 1
	db 0
	dw 0x1001, 0
	dd 0
  _runtime_unw_end

  _runtime_unw _make_identifier.1a
	db 1 + (0 shl 3)
	db _sz_prolog
	db 1
	db 0
	dw 0x1001, 0
	dd 0
  _runtime_unw_end

  _runtime_unw _make_identifier._base
	db 1 + (0 shl 3)
	db _sz_prolog
	db 2
	db 0
	dw _sz_prolog + 0x3200
	dw 0x3001
	dd 0
  _runtime_unw_end

  _runtime_unw _fMap
	db 1 + (0 shl 3)
	db _sz_prolog
	db 7
	db 5 ; RBP
	dw _sz_prolog + 0x0300
	dw .alloc - _orig + 0x5200
	dw 0xC007, 0x7005, 0x6004, 0x5003, 0x3002, 0
	dd 0
  _runtime_unw_end

  _runtime_unw _fUnmap
	db 1 + (0 shl 3)
	db _sz_prolog
	db 2
	db 0
	dw _sz_prolog + 0x3200, 0x3001
	dd 0
  _runtime_unw_end

  _runtime_unw _xcpt_table_delete
	db 1 + (0 shl 3)
	db _sz_prolog
	db 1
	db 0
	dw _sz_prolog + 0x4200, 0
	dd 0
  _runtime_unw_end

  _runtime_unw _splitcmdline2module
	db 1 + (0 shl 3)
	db _sz_prolog
	db 9
	db 5 ; RBP
	dw _sz_prolog + 0x0300
	dw 0xF00D, 0xE00B, 0xD009, 0xC007, 0x7005, 0x6004, 0x5003, 0x3002, 0
	dd 0
  _runtime_unw_end

  _runtime_unw _splitcmdline2module.1a
	db 1 + (0 shl 3)
	db _sz_prolog
	db 2
	db 5 ; RBP
	dw _sz_prolog + 0x0300
	dw .push_rbp - _orig + 0x5000
	dd 0
  _runtime_unw_end

  _runtime_unw _splitcmdline2module.heapalloc1
	db 1 + (0 shl 3)
	db _sz_prolog
	db 2
	db 0
	dw _sz_prolog + 0x3200, 0x5001
	dd 0
  _runtime_unw_end

  _runtime_unw _splitcmdline2module.heapfindsep1a
	db 1 + (0 shl 3)
	db _sz_prolog
	db 2
	db 0
	dw _sz_prolog + 0x3200, 0x5001
	dd 0
  _runtime_unw_end

  _runtime_unw _splitcmdline2module.heapstrchr1
	db 1 + (0 shl 3)
	db _sz_prolog
	db 2
	db 0
	dw _sz_prolog + 0x3200, 0x5001
	dd 0
  _runtime_unw_end

  _runtime_unw _splitcmdline2module.getlibproc1a
	db 1 + (0 shl 3)
	db _sz_prolog
	db 6
	db 5 ; RBP
	dw _sz_prolog + 0x0300
	dw 0xD007, 0x7005, 0x6004, 0x5003, 0x3002
	dd 0
  _runtime_unw_end

  _runtime_unw _splitcmdline2module.get_next
	db 1 + (0 shl 3)
	db _sz_prolog
	db 3
	db 0
	dw _sz_prolog + 0x6200
	dw 0xC005, 0xA003, 0x5001, 0
	dd 0
  _runtime_unw_end

  _runtime_unw _newproc
	db 1 + (0 shl 3)
	db _sz_prolog
	db 8
	db 5 ; RBP
	dw _sz_prolog + 0x0300
	dw .alloc - _orig + 0x0100, 136 / 8 + 11
	dw 0xC007, 0x7005, 0x6004, 0x5003, 0x3002
	dd 0
  _runtime_unw_end

  _runtime_unw _closehandles
	db 1 + (0 shl 3)
	db _sz_prolog
	db 4
	db 5 ; RBP
	dw _sz_prolog + 0x0300
	dw 0x6004, 0x5003, 0x3002
	dd 0
  _runtime_unw_end

  _runtime_unw _waitforalerted
	db 1 + (0 shl 3)
	db _sz_prolog
	db 1
	db 0
	dw _sz_prolog + 0x4200, 0
	dd 0
  _runtime_unw_end

  _runtime_unw _waitforalerted.1
	db 1 + (0 shl 3)
	db _sz_prolog
	db 5
	db 0
	dw _sz_prolog + 0x4200
	dw 0xB006, 0xA004, 0x6002, 0x3001, 0
	dd 0
  _runtime_unw_end

section '.idata' import data readable writeable
	library kernel,'KERNEL32.DLL',\
		msvcrt,'MSVCRT.DLL',\
		ntdll, 'NTDLL.DLL',\
		user,  'USER32.DLL'

  import kernel,\
	 CreateFileMapping, 'CreateFileMappingA',\
	 CreateMutex, 'CreateMutexA',\
	 CreateProcess, 'CreateProcessA',\
	 CloseHandle, 'CloseHandle',\
	 DuplicateHandle, 'DuplicateHandle',\
	 ExitProcess, 'ExitProcess',\
	 FormatMessage, 'FormatMessageA',\
	 FreeLibrary, 'FreeLibrary',\
	 GetCommandLine, 'GetCommandLineA',\
	 GetCurrentProcess, 'GetCurrentProcess',\
	 GetCurrentProcessId, 'GetCurrentProcessId',\
	 GetCurrentThread, 'GetCurrentThread',\
	 GetLastError, 'GetLastError',\
	 GetModuleHandle, 'GetModuleHandleA',\
	 GetProcAddress, 'GetProcAddress',\
	 HeapAlloc, 'HeapAlloc',\
	 HeapCreate, 'HeapCreate',\
	 HeapDestroy, 'HeapDestroy',\
	 HeapFree, 'HeapFree',\
	 LoadLibrary, 'LoadLibraryA',\
	 MapViewOfFile, 'MapViewOfFile',\
	 QueryPerformanceCounter, 'QueryPerformanceCounter',\
	 ResumeThread, 'ResumeThread',\
	 RtlDeleteFunctionTable, 'RtlDeleteFunctionTable',\
	 Sleep, 'Sleep',\
	 SleepEx, 'SleepEx',\
	 TerminateProcess, 'TerminateProcess',\
	 UnmapViewOfFile, 'UnmapViewOfFile',\
	 VirtualProtect, 'VirtualProtect',\
	 VirtualQuery, 'VirtualQuery'

  import ntdll,\
	 NtDelayExecution, 'NtDelayExecution',\
	 NtResumeThread, 'NtResumeThread',\
	 NtTestAlert, 'NtTestAlert',\
	 NtWaitForSingleObject, 'NtWaitForSingleObject'

  import msvcrt,\
	 abort, 'abort',\
	 free, 'free',\
	 malloc, 'malloc',\
	 memcpy, 'memcpy',\
	 setjmp, '_setjmp',\
	 snprintf, '_snprintf',\
	 strchr, 'strchr',\
	 strdup, '_strdup',\
	 strlen, 'strlen',\
	 strpbrk, 'strpbrk'

  import user,\
	 MessageBox, "MessageBoxA"

  ; Why no CommandLineToArgvA function?

; section '.tls' code readable writable


include 'reloc_table.inc'